#include "TraceDebug.h"
#include "MemShared.h"

#include <sys/mman.h>
#include <sys/stat.h>        /* For mode constants */
#include <fcntl.h>           /* For O_* constants */
       
MemShared::MemShared(std::string name, sint32 size):
m_shmName(name),
m_shmSize(size)
{
}
MemShared::~MemShared()
{
}
void* MemShared::attach()
{
    struct stat fdStat;
    if (m_shmName.empty() || m_shmSize<=0)
    {
        return NULL;
    }
    sint32 shm_id = shm_open(m_shmName.c_str(),O_RDWR|O_CREAT,0666);  
    if (-1==shm_id)
    {
        TRACE_ERR_CLASS("shm[%s] open error!\n",m_shmName.c_str());
        return NULL;
    }
    if (-1==ftruncate(shm_id,m_shmSize))
    {
        TRACE_ERR_CLASS("shm[%s] set size(%d) error:%s!\n",\
                        m_shmName.c_str(),m_shmSize,ERROR_STRING);
        return NULL;    
    }
    
    if (-1==fstat(shm_id,&fdStat))
    {
        TRACE_ERR_CLASS("shm[%s] fstat error:%s!\n",m_shmName.c_str(),ERROR_STRING);
        return NULL;
    }
    m_shmSize = fdStat.st_size;
    void* addr = mmap(NULL,m_shmSize,PROT_READ|PROT_WRITE,MAP_SHARED,shm_id,0);
    if (MAP_FAILED==addr)
    {
        TRACE_ERR_CLASS("shm[%s] map error:%s!\n",m_shmName.c_str(),ERROR_STRING);
        return NULL;    
    }
    return addr;
}
sint32 MemShared::detach()
{
    if (shm_unlink(m_shmName.c_str())==0)
    {
        return STATUS_OK;
    }
    TRACE_ERR_CLASS("shm[%s] fstat error:%s!\n",m_shmName.c_str(),ERROR_STRING);
    return STATUS_ERROR;
}

sint32 MemShared::getSize()
{
    return m_shmSize;
}

